/** @file gpio-linux32.c 
 * Implementiert (bzw simuliert) die GPIO-Schnittstelle auf einem 
 * 32-bit Linux System
 * 
 * @author Daniel Kummer, Sebastian Kummer
 * @date Donnerstag, Dezember 12, 2007
 * @version 1.0
 */
 
#include <stdio.h>
#include "gpio.h"
#include "gpio-port-config.h"
#include "log.h"

/**
 * Initialisiert das gpio_values[] Array
 */
void lcv_gpio_init();

/**
 * Wurden die Ports bereits initialisiert
 */
unsigned char gpio_initialised = FALSE;

/**
 * Array zur Simulation der GPIO Ports
 */
unsigned char gpio_values[sizeof(gpio_in) / sizeof(*gpio_in)];

/**
 * Function-Pointer auf den GPIO-Output-Handler
 */
void (*gpio_write_handler)(unsigned char port, unsigned char value) = NULL;


char lcv_gpio_read(unsigned char port)
{	
	lcv_gpio_init();
	if (port < gpio_in_ports_cnt) {
		return gpio_values[port];
	} else {
		return ERROR_ILLEGAL_PORT;
	}
}

char lcv_gpio_write(unsigned char port, unsigned char value)
{	
	if (port < gpio_out_ports_cnt) {
		if (gpio_write_handler != 0) { 
			(*gpio_write_handler) (port, value);
		}
		char log_entry[256];
		sprintf (log_entry, "GPIO port Number %u was written to %u", port, value);			
		lcv_log(log_entry);
		
		
		return TRUE;		
	} else {
		return ERROR_ILLEGAL_PORT;
	}
}

void lcv_gpio_init()
{
	if (!gpio_initialised) {
		int i;
		
		for (i=0; i<gpio_in_ports_cnt; i++) {
			gpio_values[i] = 1;
		}		
		gpio_initialised = TRUE;
	}
}


void lcv_gpio_simulate_input(unsigned char port, unsigned char value)
{
	if (port < gpio_out_ports_cnt) {
		if (value == 0) {
			gpio_values[port] = 0;
		} else {
			gpio_values[port] = 1;
		}
	}
}

void lcv_gpio_simulate_output(void (*handler)(unsigned char port, unsigned char value))
{
	gpio_write_handler = handler;
}
